/**
 * Copyright (c) 2016-2019 人人开源 All rights reserved.
 *
 * https://www.renren.io
 *
 * 版权所有，侵权必究！
 */

package com.xiaoniu.forum.web.resolver;

import com.xiaoniu.forum.annotation.LoginUser;
import com.xiaoniu.forum.web.interceptor.AuthorizationInterceptor;
import com.xiaoniu.forum.entity.MemberEntity;
import com.xiaoniu.forum.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 有@LoginUser注解的方法参数，注入当前登录用户
 * 主要作用：
 *      当Controller方法的参数的类型为 UserEntity 时，并且标记了 @LoginUser时，就会自动将当前用户注入到该参数中
 *
 * @author Mark sunlightcs@gmail.com
 */
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Autowired
    private MemberService memberService;

    //当该方法返回真时，就可以进入 resolveArgument方法进行参数处理
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        //当参数的类型为 UserEntity 时，并且标记了 @LoginUser时
        return parameter.getParameterType().isAssignableFrom(MemberEntity.class) && parameter.hasParameterAnnotation(LoginUser.class);
    }


    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        //获取用户ID（该用户ID是MVC拦截器设置到request域的，当用户通过拦截器的验证request就有当前用户的ID了）
        Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
        if(object == null){
            return null;
        }
        MemberEntity user = null;
        //获取用户信息
        if (object.getClass().equals(Long.class)){
            user = memberService.getById((Long)object);
        }else {
            user = memberService.getById((String)object);
        }


        return user;
    }
}
